package fluxx.mvc;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import fluxx.draft.CardPile;
import fluxx.draft.Deck;
import fluxx.draft.ImmutableCardSet;
import fluxx.draft.Card;
import fluxx.draft.CardSet;
import fluxx.draft.Goal;
import fluxx.draft.Player;

public class Model {
	private static final int INIT_HAND_SIZE = 3;
	private CardPile fresh = new CardPile();
	private CardSet discard = new CardSet();
	private CardSet rules = new CardSet();
	private Goal goal = null;
	private Player[] players;
	private PropertyChangeSupport change = new PropertyChangeSupport(this);
	
	public enum Pile {
		FRESH, DISCARD, RULES;
	}
	public enum PlayerPile {
		HAND, KEEPERS;
	}
	
	public Model (Deck deck, int numPlayers) {
		this.fresh = new CardPile(deck.getDeck());
		/*for (Card card : deck) this.fresh.add(card);
		this.fresh.shuffle();*/
		
		players = new Player[numPlayers];
		for (int i = 0; i < numPlayers; i++) {
			players[i] = new Player();
			for (Card card : fresh.take(INIT_HAND_SIZE)) {
				players[i].give(card);
			}
		}
	}
	
	public ImmutableCardSet getFresh() {
		return new ImmutableCardSet(fresh);
	}
	public ImmutableCardSet getDiscard() {
		return new ImmutableCardSet(discard);
	}
	public ImmutableCardSet getRules() {
		return new ImmutableCardSet(rules);
	}
	public Goal getGoal() {
		// Card is immutable so this is cool.
		return goal;
	}
	public ImmutableCardSet getHand(Player player) {
		return new ImmutableCardSet(player.getHand()); // ???
	}
	public ImmutableCardSet getKeepers(Player player) {
		return new ImmutableCardSet(player.getKeepers());
	}
	public void addGoal(Goal newGoal) {
		discard.add(goal);
		this.goal = newGoal;
	}
	
	// How about players? getPlayers? getHand(Player)?
	private CardSet pileToCardSet (Pile pile) {
		switch (pile) {
		case FRESH:
			//return fresh;
		case DISCARD:
			return discard;
		default:
		case RULES:
			return rules;
		}
	}
	private CardSet pileToCardSet (Player player, PlayerPile pile) {
		switch (pile) {
		case HAND:
			return player.getHand();
		default:
		case KEEPERS:
			return player.getKeepers();
		}
	}
	
	// Moving cards around
	public void take (Pile pile, Card card) {
		pileToCardSet(pile).remove(card);
	}
	public void take (Player player, PlayerPile pile, Card card) {
		pileToCardSet(player, pile).remove(card);
	}
	public void give (Pile pile, Card card) {
		pileToCardSet(pile).add(card);
	}
	public void give (Player player, PlayerPile pile, Card card) {
		pileToCardSet(player, pile).add(card);
	}
	// Predefined card moves
	/*public void discard (Player player, PlayerPile pile, Card card) {
		take(player, pile, card);
		give(Pile.DISCARD, card);
	}
	public void discard (Pile pile, Card card) {
		take(pile, card);
		give(Pile.DISCARD, card);
	}*/
	
	public void addListener(PropertyChangeListener listener) {
		change.addPropertyChangeListener(listener);
	}
	public void removeListener(PropertyChangeListener listener) {
		change.removePropertyChangeListener(listener);
	}
}
